//定义promise状态常量
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
let _id = 0;
//自定义promise对象
class MyPromise {
    //promise构造器。定义时参数为一个函数
    constructor(fn){
        try{
        //promise的g构造函数调用即执行
            fn(this.resolve,this.reject);
            this.id = _id;
            _id++;
        }catch(e){
            this.reject(e);
        }
    }
    //初始化promise状态
    status = PENDING;
    //初始化成功状态的值
    successValue = undefined;
    //初始化失败状态的值
    errorValue = undefined;
    //定义then方法的回调函数待执行列表
    successFnList = [];
    errorFnList = [];

    resolve = (value) => {
        //只有pending状态才能执行回调函数，其他状态无效
        if(this.status != PENDING) return;
        this.status = FULFILLED;
        this.successValue = value;
        //构造函数内部如果异步调用  then方法会放到fnList暂存，等待执行resolve时遍历执行
        while(this.successFnList.length) this.successFnList.shift()();
    }
    reject = (err) => {
        //只有pending状态才能执行回调函数，其他状态无效
        if(this.status != PENDING) return;
        this.status = REJECTED;
        this.errorValue = err;
        //构造函数内部如果异步调用  then方法会放到fnList暂存，等待执行resolve时遍历执行
        while(this.errorFnList.length) this.errorFnList.shift()();
    }
    then(successFn,errorFn){
        //then方法的两个参数都是可选参数，如果参数不存在处理
        successFn = successFn || (value => value);
        errorFn = errorFn || (err => {throw err});
        //then方法会返回一个新的promise对象
        let promise2 = new MyPromise((resolve,reject) => {
            if(this.status == FULFILLED){
                setTimeout(() => {
                    try{
                        let x= successFn(this.successValue);
                        checkPromise(promise2,x,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                }, 0);
            }else if(this.status == REJECTED){
                setTimeout(() => {
                    try{
                        let x= errorFn(this.errorValue);
                        checkPromise(promise2,x,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                }, 0);
            }else{
                this.successFnList.push(()=>{
                    setTimeout(() => {
                        try{
                            let x= successFn(this.successValue);
                            checkPromise(promise2,x,resolve,reject);
                        }catch(e){
                            reject(e);
                        }
                    }, 0);
                })
                this.errorFnList.push(()=>{
                    setTimeout(() => {
                        try{
                            let x= errorFn(this.errorValue);
                            checkPromise(promise2,x,resolve,reject);
                        }catch(e){
                            reject(e);
                        }
                    }, 0);
                })
            }
        });
        return promise2;

    }
    finally(fn){
        //finally 后可以继续调用then方法  所以要返回一个promise对象
        return this.then(
            //等待fn执行完毕后把值传递给下一个then方法 这里的value和err错误信息都是上一个promise对象的结果
            //fn的返回值即使是promise，这个promise计算的结果也不会传递给下个then方法
            value => MyPromise.resolve(fn()).then(() => value),
            err => MyPromise.resolve(fn()).then(() => {throw err})
            )
    }
    catch(errorFn){
        //当then方法不传递错误处理函数时   会链式调用catch方法处理
        return this.then(undefined,errorFn)
    }
    static resolve(value){
        //参数是promise对象直接返回，否则创建promise对象并返回
        if(value instanceof MyPromise){
            return value;
        }else{
            return new MyPromise(resolve => resolve(value));
        }
    }
    static all(array){
        
        //all方法会返回一个promise对象
        let promise = new MyPromise((resolve,reject) => {
            //定义当前数组已执行个数
            let arrIndex = 0;
            //定义返回值数组
            let resultList = [];
            function doneFunction (value,index) {
                resultList[index] = value;
                arrIndex++;
                if(arrIndex == array.length){
                    resolve(resultList);
                }
            }
            array.forEach((item,index) => {
                //元素如果是promise对象要等promise执行完毕后返回给结果数组
                if(item instanceof MyPromise){
                    item.then(value => doneFunction(value,index),err => reject(err))
                }else{
                    doneFunction(item,index)
                }
            });
        });
        return promise
    }
}

function checkPromise(promise,x,resolve,reject){
    //如果then方法返回的promise对象是创建的promise对象自己   禁止调用
    if(promise === x) {
        return reject(new TypeError('不能自己调用自己'))
    }
    //如果返回的是promise 对象，直接调用promise的then方法返回
    if(x instanceof MyPromise){
        return x.then(resolve,reject);
    }
    //如果是普通对象，直接调用resolve方法
    resolve(x);
}


let promise = new MyPromise((resolve,reject) => {
    setTimeout(() => {
        //resolve(100);
        reject(200);
    }, 2000);
});
let promise2 = new MyPromise((resolve,reject) => {
    //setTimeout(() => {
        resolve(100);
        //reject(200);
    //}, 1000);
});
promise.then(value => {
    console.log("value1",value);
    return promise2
}).catch(err => {
    console.log("catch",err)
})
// promise3.then(value => {
//     console.log("value2",value);
// },err => {
//     console.log('err2',err);
// })

// MyPromise.all([1,2,"3",promise,"4",promise2]).then(value => {
//     console.log(value)
// },err => {
//     console.log(err)
// })